//
#include "Retarget.h"

/*delay variable*/
static __IO uint32_t fac_us;
static __IO uint32_t fac_ms;
//
#ifdef __cplusplus
namespace std
{
  extern "C" {
#endif

/* Suport printf function, useMicroLib is unnecessary */
#ifdef __CC_ARM
  #pragma import(__use_no_semihosting)
  struct __FILE
  {
    int handle;
  };
  
  FILE __stdout;
  
  void _sys_exit(int x)
  {
    x = x;
  }
#endif

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{  
  USART_SendData(PRINT_UART, ch);
  while ( USART_GetFlagStatus(PRINT_UART, USART_FLAG_TRAC) == RESET );    
  return ch;
}

#ifdef __cplusplus
  } /* extern "C" */
} /* namespace */
#endif



/******************************************************************************
  * @brief  initialize Delay function   
  * @param  None
  * @retval None
******************************************************************************/
void Delay_init()
{
    /*Config Systick*/
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
    fac_us = SystemCoreClock / (1000000U);
    fac_ms = fac_us * (1000U);
}

/******************************************************************************
  * @brief  Inserts a delay time.
  * @param  nus: specifies the delay time length, in microsecond.
  * @retval None
******************************************************************************/
void Delay_us(u32 nus)
{
u32 temp = 0;
//
    SysTick->LOAD = (u32)(nus*fac_us);
    SysTick->VAL = 0x00;
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ;
    do
    {
        temp = SysTick->CTRL;
    }while((temp & 0x01) &&! (temp & (1<<16)));

    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
    SysTick->VAL = 0x00;
}

/******************************************************************************
  * @brief  Inserts a delay time.
  * @param  nms: specifies the delay time length, in milliseconds.
  * @retval None
******************************************************************************/
void Delay_ms(u16 nms)
{
u32 temp = 0;
//
    while(nms)
    {
        if(nms > STEP_DELAY_MS)
        {
            SysTick->LOAD = (u32)(STEP_DELAY_MS * fac_ms);
            nms -= STEP_DELAY_MS;
        }
        else
        {
            SysTick->LOAD = (u32)(nms * fac_ms);
            nms = 0;
        }
        SysTick->VAL = 0x00;
        SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
        do
        {
            temp = SysTick->CTRL;
        }while( (temp & 0x01) && !(temp & (1<<16)) );

        SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
        SysTick->VAL = 0x00;
    }
}

/******************************************************************************
  * @brief  Inserts a delay time.
  * @param  sec: specifies the delay time length, in seconds.
  * @retval None
******************************************************************************/
void Delay_sec(u16 sec)
{
u16 i;
//
    for(i=0; i<sec; i++)
    {
        Delay_ms(500);
        Delay_ms(500);
    }
}
	
/*****************************************************************************
  * @brief  initialize UARTx   
  * @param  bound: UART BaudRate
  * @retval None
******************************************************************************/
void UART_Print_Init(uint32_t bound)
{
    GPIO_InitType GPIO_InitStructure = {0};
    USART_InitType USART_InitStructure = {0};
    
    /*Configure the UART TX pin*/
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pins = PRINT_UARTTX_PIN; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
    GPIO_Init(PRINT_UARTTX_GPIO, &GPIO_InitStructure);
    
    /*Configure the UART RX pin*/
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pins = PRINT_UARTRX_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Pull = GPIO_Pull_PU;
    GPIO_Init(PRINT_UARTRX_GPIO, &GPIO_InitStructure);
    
    /*Configures the AF pins*/
    GPIO_PinAFConfig(GPIOA, GPIO_PinsSource2, GPIO_AF_1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinsSource3, GPIO_AF_1);
    
    /*Configure UART param*/
    USART_StructInit(&USART_InitStructure);
    USART_InitStructure.USART_BaudRate = bound;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	
    USART_Init(PRINT_UART, &USART_InitStructure); 
    USART_INTConfig(PRINT_UART, USART_INT_RDNE, ENABLE);
    USART_Cmd(PRINT_UART, ENABLE);
}
//=========================================================================================

